package org.demo.rc.client;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.SocketException;
import java.net.URL;
import java.text.ParseException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.border.EmptyBorder;

/**
 * 远程控制：客户端界面
 * @author  
 * @date    2010-10-23
 * @file    org.demo.rc.MonitorGUI.java
 */
public class MonitorGUI {

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		new MonitorGUI();
	}
	// 主窗体
	private JFrame win;
	private JToolBar toolBar;
	private JImagePanel imgPanel;
	private ButtonListener btnListener;
	// 添加连接窗口
	private JFrame conn_win;
	private JTextField conn_txt_ip = null;
	private JTextField conn_txt_port = null;
	// 
	private MonitorClient client;
	private Thread img_task;
	private Thread img_refresh_task;
	/**
	 * 构造函数
	 * @throws SocketException 
	 * @throws ParseException 
	 */
	public MonitorGUI() throws SocketException, ParseException{
		init();
		initConnWin();
		client = new MonitorClient();
		img_task = new Thread(new ImageConsumeTask(client,imgPanel));
		img_refresh_task = new Thread(new ImageRefreshTask(client));
		img_refresh_task.setDaemon(true);
		img_task.start();		
	}
	/**
	 * 初始化
	 */
	private void init(){
		JFrame.setDefaultLookAndFeelDecorated(true);
		win = new JFrame("远程控制");
		win.setLayout(new BorderLayout());
		// 
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		Insets insets =Toolkit.getDefaultToolkit().getScreenInsets(win.getGraphicsConfiguration());
		win.setBounds(
			insets.left,insets.top, 
		    (int)screen.getWidth() - (insets.left + insets.right), 
			(int)screen.getHeight() - (insets.top + insets.bottom));
		// 
		toolBar = new JToolBar();
		btnListener = new ButtonListener();		
		toolBar.add(makeButton("connect.png","连接","connect"));
		toolBar.add(makeButton("disconnect.png","断开","disconnect"));
		win.add(toolBar,BorderLayout.NORTH);
		// 
		imgPanel = new JImagePanel();
		imgPanel.addMouseListener(new ImageMouseListener());
		imgPanel.addMouseMotionListener(new ImageMouseMotionListener());
		imgPanel.addMouseWheelListener(new ImageMouseWheelListener());
		win.add(new JScrollPane(imgPanel),BorderLayout.CENTER);
		// 
		Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
			/**
			 * 监听键盘的 press,release事件
			 */
			public void eventDispatched(AWTEvent event) {
				KeyEvent kevt = null;
				if (event instanceof KeyEvent){
					kevt = (KeyEvent)event;
					if (event.getID() == KeyEvent.KEY_PRESSED){
						MonitorGUI.this.sendKey(KeyEvent.KEY_PRESSED,kevt.getKeyCode(),kevt.getKeyChar(),kevt.getKeyLocation());
					} else if (event.getID() == KeyEvent.KEY_RELEASED){
						MonitorGUI.this.sendKey(KeyEvent.KEY_RELEASED,kevt.getKeyCode(),kevt.getKeyChar(),kevt.getKeyLocation());
					}
				}				
			}
		}, AWTEvent.KEY_EVENT_MASK);
		// 
		win.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				MonitorGUI.this.close();				
			}
		});			
		win.setVisible(true);
	}
	/**
	 * 初始化连接窗口
	 * @throws ParseException 
	 */
	private void initConnWin() throws ParseException{
		conn_win = new JFrame("连接");
		conn_win.setLayout(null);
		int width=300,height=200;
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		int left = (int)(screen.getWidth()-width)/2;
		int top = (int)(screen.getHeight()-height)/2;
		conn_win.setBounds(left, top, width, height);
		JLabel lab_ip = new JLabel("IP：");
		JLabel lab_port = new JLabel("PORT：");
		conn_txt_ip = new JTextField("10.162.11.192",15);
		conn_txt_port = new JTextField("9980",6);
		JButton btn_ok = makeButton(null, "确定", "connect_ok");
		lab_ip.setBounds(60, 30, 40, 32);
		conn_txt_ip.setBounds(100, 30, 120, 32);
		lab_port.setBounds(60, 70, 40, 32);
		conn_txt_port.setBounds(100, 70, 90, 32);
		btn_ok.setBounds(200, 120, 72, 32);
		conn_win.add(lab_ip);
		conn_win.add(conn_txt_ip);
		conn_win.add(lab_port);
		conn_win.add(conn_txt_port);
		conn_win.add(btn_ok);
		conn_win.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
	}
	/**
	 * 创建按钮
	 * @param filename
	 * @param text
	 * @param command
	 * @return
	 */
	private JButton makeButton(String filename,String text,String command){
		JButton btn = null;
		if (filename != null){
			URL url = this.getClass().getResource(filename);
			ImageIcon icon = new ImageIcon(url);
			Image image = icon.getImage();
			image = image.getScaledInstance(32, 32, Image.SCALE_SMOOTH);
			icon.setImage(image);
			btn = new JButton(text + "  ", icon);
			btn.setBorder(new EmptyBorder(0, 0, 0, 0));
		} else {
			btn = new JButton(text);
			btn.setMargin(new Insets(0,0,0,0));
		}
		// 
		btn.setActionCommand(command);
		btn.addActionListener(btnListener);
		return btn;
	}
	/**
	 * 连接
	 * @param ip
	 * @param port
	 */
	public void connect(String ip,int port){
		if (client != null){
		    client.connect(ip, port);
		    if (img_refresh_task.getState() == Thread.State.NEW){
				img_refresh_task.start();
			}
		}		
	}
	/**
	 * 断开
	 */
	private void disconnect(){
		if (client != null){
			client.disconnect();
			try {
				if (client.getImgQueue().size() != 0){
					client.getImgQueue().clear();
				}
				// 等待当前的图像绘制完毕
				Thread.sleep(1500);
				imgPanel.setImage(null);
				imgPanel.updateUI();
			} catch (Exception e){
			}
		}
	}
	/**
	 * 关闭
	 */
	public void close(){
		disconnect();
		client.close();
		System.exit(0);
	}
	/**
	 * 发送键盘事件
	 * @param type
	 * @param code
	 * @param c
	 * @param location
	 */
	public void sendKey(int type,int code,char c,int location){
		if (client == null || client.getCurrentHost() == null){
			return;
		}
		String cmd = "";
		if (type == KeyEvent.KEY_PRESSED){
			cmd = "keyPressed;" + code;
		} else if (type == KeyEvent.KEY_RELEASED){
			cmd = "keyReleased;" + code;
		}
		if (!cmd.equals("")){
			client.sendCommand(cmd);
		}
	}
	/**
	 * 发送鼠标事件
	 * @param type
	 * @param x
	 * @param y
	 * @param buttons
	 */
	public void sendMouse(int type,int x,int y,int buttons){
		if (client == null || client.getCurrentHost() == null){
			return;
		}
		StringBuffer cmd = new StringBuffer();
		int btnMask = 0;
		if (buttons == MouseEvent.BUTTON1){
			btnMask = MouseEvent.BUTTON1_MASK;
		} else if (buttons == MouseEvent.BUTTON2){
			btnMask = MouseEvent.BUTTON2_MASK;
		} else if (buttons == MouseEvent.BUTTON3){
			btnMask = MouseEvent.BUTTON3_MASK;
		}
		if (type == MouseEvent.MOUSE_MOVED){
			cmd.append("mouseMove;");
			cmd.append(x).append(";");
			cmd.append(y);
		} else if (type == MouseEvent.MOUSE_PRESSED){
			cmd.append("mousePress;");
			cmd.append(btnMask);
		} else if (type == MouseEvent.MOUSE_RELEASED){
			cmd.append("mouseRelease;");
			cmd.append(btnMask);
		} else if (type == MouseEvent.MOUSE_WHEEL){
			cmd.append("mouseWheel;");
			cmd.append(btnMask);
		} 
		if (!cmd.equals("")){			
			client.sendCommand(cmd.toString());
		}
	}
	/**
	 * 按钮监听
	 * @author 
	 *
	 */
	private class ButtonListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			String cmd = e.getActionCommand();
			if ("connect".equals(cmd)){
				MonitorGUI.this.conn_win.setVisible(true);
			} else if ("connect_ok".equals(cmd)){
				String ip = conn_txt_ip.getText();
				int port = Integer.parseInt(conn_txt_port.getText());
				MonitorGUI.this.conn_win.dispose();
				MonitorGUI.this.connect(ip,port);
			} else if ("disconnect".equals(cmd)){
				MonitorGUI.this.disconnect();
			}
		}
	}	
	/**
	 * 监听鼠标
	 * @author 
	 *
	 */
	private class ImageMouseListener implements MouseListener{
		public void mouseEntered(MouseEvent e) {
			// 
		}
		public void mouseExited(MouseEvent e) {
			// 
		}
		public void mouseClicked(MouseEvent e) {
			// 
		}
		public void mousePressed(MouseEvent e) {
			sendMouse(MouseEvent.MOUSE_PRESSED,e.getX(),e.getY(),e.getButton());
		}
		public void mouseReleased(MouseEvent e) {
			sendMouse(MouseEvent.MOUSE_RELEASED,e.getX(),e.getY(),e.getButton());
		}
	}
	/**
	 * 监听鼠标移动
	 * @author 
	 *
	 */
	private class ImageMouseMotionListener implements MouseMotionListener{
		public void mouseDragged(MouseEvent e) {
			sendMouse(MouseEvent.MOUSE_MOVED,e.getX(),e.getY(),e.getButton()); 
		}
		public void mouseMoved(MouseEvent e) {
			sendMouse(MouseEvent.MOUSE_MOVED,e.getX(),e.getY(),e.getButton());
		}
	}
	/**
	 * 监听鼠标滚动
	 * @author 
	 *
	 */
	private class ImageMouseWheelListener implements MouseWheelListener{
		public void mouseWheelMoved(MouseWheelEvent e) {
			int wheelAmt = e.getUnitsToScroll() * e.getScrollAmount();
			sendMouse(MouseEvent.MOUSE_WHEEL,e.getX(),e.getY(),wheelAmt);
		}
	}
}
